package com.unionfetch.content_home.ui.auth

import android.Manifest
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.text.TextUtils
import android.view.KeyEvent
import android.view.View
import android.widget.Button
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.unionfetch.content_home.R
import com.unionfetch.content_home.adapter.UploadItemAdapter
import com.unionfetch.content_home.bean.AddressType
import com.unionfetch.content_home.bean.UploadItem
import com.unionfetch.content_home.bean.UploadType
import com.unionfetch.content_home.bean.request.AddressKYCFileType
import com.unionftech.common.common.bean.KYCFileInfo
import com.unionfetch.content_home.bean.request.UploadKYCFile
import com.unionfetch.content_home.contract.KYCContract
import com.unionfetch.content_home.presenter.KYCPresenter
import com.unionfetch.content_home.ui.dialog.CustomSelectDialog
import com.unionfetch.content_home.ui.dialog.CustomTipDialog
import com.unionftech.baselibrary.network.RetrofitClient
import com.unionftech.common.CommonConstants
import com.unionftech.common.R.color
import com.unionftech.common.R.string
import com.unionftech.common.aspectj.PermissionRequest
import com.unionftech.common.base.IUpdate
import com.unionftech.common.base.mvp.annitation.InjectPresenter
import com.unionftech.common.base.mvp.impl.BaseMvpActivity
import com.unionftech.common.bean.ResponseResult
import com.unionftech.common.bean.toast
import com.unionftech.common.common.GlobalInfoManager
import com.unionftech.common.common.bean.SystemUserInfo
import com.unionftech.common.common.language.DynamicResourceManager
import com.unionftech.common.common.model.CommonModel
import com.unionftech.common.common.ui.FullScreenImageActivity
import com.unionftech.common.network.UploadListener
import com.unionftech.common.utils.LogUtils
import com.unionftech.common.utils.ToastUtils
import com.unionftech.common.utils.UploadFileLifecycleObserver
import com.unionftech.common.utils.Utils
import com.unionftech.common.webview.CommonWebViewActivity
import java.io.File

class AddressAuthActivity : BaseMvpActivity(), IUpdate, KYCContract.IUploadPoaView {
    private val mBtnConfirm by lazy { findViewById<Button>(R.id.btn_confirm) }
    private val mRvImages by lazy { findViewById<RecyclerView>(R.id.rv_images) }
    private val mTvSupportUploadTip by lazy { findViewById<TextView>(R.id.tv_support_upload_tip) }
    private val mTvDocUploadTitle by lazy { findViewById<TextView>(R.id.tv_doc_upload_title) }
    private val mTvDocType by lazy { findViewById<TextView>(R.id.tv_doc_type) }
    private val mRlDocTypeContainer by lazy { findViewById<RelativeLayout>(R.id.rl_doc_type_container) }
    private val mTvDocTypeTitle by lazy { findViewById<TextView>(R.id.tv_doc_type_title) }
    private val mAddItem = UploadItem(itemType = UploadItem.ADD_ITEM)
    private val mDataList: MutableList<UploadItem> = mutableListOf(mAddItem)
    private lateinit var mAdapter: UploadItemAdapter
    private lateinit var mUploadObserver: UploadFileLifecycleObserver
    private var mAddressTypeIndex = -1
    private var mIsSupplement = false
    private val mCommonModel by lazy { CommonModel() }
    private var mMaxSelectCount = 2
    private var mMinSelectCount = 2

    @InjectPresenter
    private lateinit var mKYCPresenter: KYCPresenter

    companion object {
        private const val IMAGE_URL_PATH = CommonConstants.Value.UPLOAD_URL_PATH
        private const val TAG = "AddressAuthActivity"
        private const val PARAMS_IS_SUPPLEMENT = "params_is_supplement"
        private val SUFFIX_IMAGE = listOf("png", "jpg", "jpeg", "pdf")
        private const val MAX_FILE_SIZE = 20 //单位M

        @JvmStatic
        fun startThis(context: Context, isSupplement: Boolean) {
            Intent(context, AddressAuthActivity::class.java).apply {
                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                putExtra(PARAMS_IS_SUPPLEMENT, isSupplement)
                context.startActivity(this)
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        mUploadObserver = UploadFileLifecycleObserver(activityResultRegistry, 2)
        lifecycle.addObserver(mUploadObserver)
        super.onCreate(savedInstanceState)
    }

    override fun obtainIntentData(intent: Intent) {
        super.obtainIntentData(intent)
        mIsSupplement = intent.getBooleanExtra(PARAMS_IS_SUPPLEMENT, false)
    }

    override fun initLayout() = R.layout.activity_address_auth


    override fun initLanguageText() {
        super.initLanguageText()
        mTvDocTypeTitle.text = DynamicResourceManager.getString(string.document_type)
        mTvDocType.hint = DynamicResourceManager.getString(string.please_select)
        mTvDocUploadTitle.text = DynamicResourceManager.getString(string.document_upload)
        mTvSupportUploadTip.text =
            DynamicResourceManager.getString(string.support_upload_img_type)
        mBtnConfirm.text = DynamicResourceManager.getString(string.confirm)
    }

    override fun initData() {
        super.initData()
        mAdapter = UploadItemAdapter(mContext, mDataList)
    }


    override fun setListener() {
        super.setListener()
        mRlDocTypeContainer.setOnClickListener(this)
        mBtnConfirm.setOnClickListener(this)
        mAdapter.setOnItemClickListener { _, _, position ->
            mDataList.getOrNull(position)?.also { item ->
                if (item.itemType == UploadItem.ADD_ITEM) {
                    //展示证件上传方式
                    showSelectPhotoWayDialog()
                }
            }
        }
        mAdapter.setOnItemChildClickListener { adapter, view, position ->
            LogUtils.d(TAG, "setOnItemChildClickListener-->position:${position}")
            when (view.id) {
                R.id.iv_delete_img -> {
                    mDataList.removeAt(position)
                    adapter.notifyItemRemoved(position)
                    checkButtonEnable()
                    checkAddItem()
                }

                R.id.iv_image -> {
                    //展示图片
                    mDataList.getOrNull(position)?.also {
                        if (it.uploadState == UploadItem.State.SUCCESS) {
                            FullScreenImageActivity.startThis(mContext, it.url.toString())
                        }
                    }
                }

                R.id.iv_pdf -> {
                    mDataList.getOrNull(position)?.also {
                        if (it.uploadState == UploadItem.State.SUCCESS) {
                            CommonWebViewActivity.startPdfFile(
                                mContext, it.name ?: "查看PDF", it.url.toString()
                            )
                        }
                    }
                }
            }
        }
        mUploadObserver.setResultCallBack { uri, type ->
            if (checkCanAdd()) {
                uploadItem(uri, type)
            }
        }
    }

    private fun checkAddItem() {
        var count = 0
        for (item in mDataList) {
            if (item.itemType != UploadItem.ADD_ITEM && item.uploadState != UploadItem.State.FAILED) {
                count++
            }
        }
        if (count < mMaxSelectCount) {
            if (!mDataList.contains(mAddItem)) {
                mDataList.add(mAddItem)
                mAdapter.notifyItemInserted(mDataList.size - 1)
            }
        }
    }

    private fun checkCanAdd(): Boolean {
        var count = 1
        for (item in mDataList) {
            if (item.itemType != UploadItem.ADD_ITEM && item.uploadState != UploadItem.State.FAILED) {
                count++
            }
        }
        if (count > mMaxSelectCount) {
            return false
        }
        if (count == mMaxSelectCount) {
            mDataList.remove(mAddItem)
            val index = mDataList.size - 1
            mAdapter.notifyItemRemoved(index)
            return true
        }
        return true
    }

    private fun uploadItem(uri: Uri, type: String) {
        Utils.uriToFile(mContext, uri)?.also { file ->
            LogUtils.d(TAG, "uploadItem:type-->$type  uri->$uri  ")
            //判断文件的格式
            val isSupport = SUFFIX_IMAGE.contains(file.extension.lowercase())
            //判断文件是否过大，如果过大直接展示失败
            val isLimit = Utils.checkFileSizeIsLimit(file.length(), MAX_FILE_SIZE, "M")
            val item = obtainUploadItem()
            val isContainsErrorItem = mDataList.contains(item)
            val uploadItem = item.apply {
                localPath = uri
                error = if (!isSupport) {
                    DynamicResourceManager.getString(mContext, string.document_type_error)
                } else if (isLimit) {
                    DynamicResourceManager.getString(mContext, string.file_too_large)
                } else {
                    null
                }
                uploadState = if (!isSupport || isLimit) {
                    UploadItem.State.FAILED
                } else {
                    UploadItem.State.DEFAULT
                }
                itemType = if (type == UploadFileLifecycleObserver.OPEN_PDF) {
                    UploadItem.PDF_ITEM
                } else {
                    UploadItem.IMAGE_ITEM
                }
                name = if (type == UploadFileLifecycleObserver.OPEN_PDF) {
                    file.name.removeSuffix(".pdf")
                } else {
                    file.name
                }
            }
            if (!isContainsErrorItem) {
                val addIndex = mDataList.indexOf(mAddItem)
                if (addIndex != -1) {
                    mDataList.add(addIndex, uploadItem)
                } else {
                    mDataList.add(uploadItem)
                }
            }
            if (!isLimit) {
                submitUpload(file, uploadItem)
            } else {
                checkAddItem()
                mAdapter.notifyDataSetChanged()
            }
        }

    }

    private fun obtainUploadItem(): UploadItem {
        for (uploadItem in mDataList) {
            if (!TextUtils.isEmpty(uploadItem.error)) {
                return uploadItem
            }
        }
        return UploadItem(itemType = UploadItem.IMAGE_ITEM)
    }

    private fun submitUpload(file: File, uploadItem: UploadItem) {
        mCommonModel.upload(file, object : UploadListener {
            override fun onProgressUpdate(percentage: Int) {
                runOnUiThread {
                    uploadItem.progress = percentage
                    uploadItem.uploadState = UploadItem.State.UPLOADING
                    mAdapter.notifyDataSetChanged()
                }
            }

            override fun onError(e: Exception) {
                runOnUiThread {
                    uploadItem.uploadState = UploadItem.State.FAILED
                    uploadItem.error = DynamicResourceManager.getString(string.upload_failed)
                    replaceErrorItem(uploadItem)
                    checkAddItem()
                    mAdapter.notifyDataSetChanged()
                }
            }

            override fun onFinish(url: String) {
                runOnUiThread {
                    uploadItem.uploadState = UploadItem.State.SUCCESS
                    val baseUrl = RetrofitClient.getInstance().getNetWork()
                        .getUrlMap()[RetrofitClient.KEY_BASE_URL]
                    uploadItem.url = "$baseUrl${IMAGE_URL_PATH}?path=$url"
                    uploadItem.path = url
                    replaceErrorItem(uploadItem)
                    checkAddItem()
                    mAdapter.notifyDataSetChanged()
                    checkButtonEnable()
                }
            }
        })
    }

    private fun replaceErrorItem(uploadItem: UploadItem) {
        var hasReplace = false
        for (item in mDataList) {
            if (uploadItem == item) {
                continue
            }
            if (item.uploadState == UploadItem.State.FAILED) {
                hasReplace = true
                item.apply {
                    itemType = uploadItem.itemType
                    url = uploadItem.url
                    path = uploadItem.path
                    localPath = uploadItem.localPath
                    name = uploadItem.name
                    progress = uploadItem.progress
                    error = uploadItem.error
                    uploadState = uploadItem.uploadState
                }
                break
            }
        }
        if (hasReplace) {
            mDataList.remove(uploadItem)
        }
    }

    override fun setView() {
        super.setView()
        hideCenterTitle()
        initTitleBar()
        mRvImages.layoutManager = GridLayoutManager(
            mContext, 2, GridLayoutManager.VERTICAL, false
        )
        mRvImages.adapter = mAdapter
    }

    private fun initTitleBar() {
        setBackText(
            DynamicResourceManager.getString(string.proof_of_address),
            mContext.resources.getColor(
                color.color_1C1D21
            )
        )
    }

    override fun doClick(v: View?) {
        super.doClick(v)
        when (v?.id) {
            R.id.rl_doc_type_container -> {
                //弹出证件类型
                showAddressTypeDialog()
            }

            R.id.btn_confirm -> {
                //提交poa身份认证
                submit()
            }
        }
    }

    /**
     * 屏蔽物理返回键
     */
    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        return if (keyCode == KeyEvent.KEYCODE_BACK) {
            true
        } else super.onKeyDown(keyCode, event)
    }

    override fun backPressed(): Boolean {
        showLeaveDialog()
        return true
    }

    private fun showLeaveDialog() {
        val dialog = CustomTipDialog(mContext)
        dialog.setTopRes(R.drawable.ic_circle_warning)
            .setTitle(DynamicResourceManager.getString(mContext, string.confirm_leave))
            .setCancelText(
                DynamicResourceManager.getString(
                    mContext, string.cancel
                )
            ).setConfirmText(
                DynamicResourceManager.getString(
                    mContext, string.confirm
                )
            ).setCallBack { confirm ->
                if (confirm) {
                    onBackPressedDispatcher.onBackPressed()
                }
                dialog.dismiss()
            }.show()
    }

    private fun submit() {
        getRequest()?.also { request ->
            val userToken = GlobalInfoManager.getInstance().getUserToken()
            mKYCPresenter.uploadPoa(userToken, request, mIsSupplement)
        }
    }

    private fun getRequest(): UploadKYCFile? {
        //检查证件类型
        if (mAddressTypeIndex == -1) {
            return null
        }
        val category = AddressType.entries[mAddressTypeIndex].type
        //检查证件上传的数量必须要大于最低要求
        val list = mutableListOf<UploadItem>()
        list.addAll(mDataList)
        list.remove(mAddItem)
        if (list.size < mMinSelectCount) {
            ToastUtils.longToast(
                DynamicResourceManager.getString(string.upload_least_two_files)
            )
            return null
        }
        val userInfo = GlobalInfoManager.getInstance().getSystemUserInfo() ?: return null
        //开始组装上传参数
        val files = mutableListOf<KYCFileInfo>()
        for ((index, uploadItem) in list.withIndex()) {
            val kycFileType = AddressKYCFileType.entries[index]
            val kycFileInfo = KYCFileInfo(
                type = kycFileType.type, uri = uploadItem.path.toString()
            )
            files.add(kycFileInfo)
        }
        val fileInfo = UploadKYCFile(
            files = files, userId = userInfo.userId.toString(), category = category
        )
        return fileInfo
    }

    private fun showAddressTypeDialog() {
        val list = mutableListOf<String>()
        for (type in AddressType.entries) {
            list.add(type.showName)
        }
        val selectDialog = CustomSelectDialog(mContext)
        selectDialog.setTitle(DynamicResourceManager.getString(string.document_type))
        selectDialog.setSelectIndex(mAddressTypeIndex)
        selectDialog.setItemData(list)
        selectDialog.setCallBack { index ->
            list.getOrNull(index)?.also { result ->
                mTvDocType.text = result
                mAddressTypeIndex = index
                checkButtonEnable()
            }
        }.show()
    }

    private fun showSelectPhotoWayDialog() {
        val list = mutableListOf<String>()
        for (type in UploadType.entries) {
            list.add(type.showName)
        }
        val selectDialog = CustomSelectDialog(mContext)
        selectDialog.setTitle(DynamicResourceManager.getString(string.document_upload))
        selectDialog.setItemData(list)
        selectDialog.setCallBack { index ->
            UploadType.entries.getOrNull(index)?.also { result ->
                when (result) {
                    UploadType.ALBUM -> {
                        //选择相册
                        mUploadObserver.openPickerPhoto()
                    }

                    UploadType.TAKE_PHOTO -> {
                        //选择相机
                        openCamera()
                    }

                    UploadType.SELECT_DOC -> {
                        //选择文件
                        mUploadObserver.openPdfDocument()
                    }
                }
            }
        }.show()
    }

    @PermissionRequest(
        Manifest.permission.CAMERA
    )
    private fun openCamera() {
        mUploadObserver.takePhoto(mContext)
    }

    private fun checkUploadFileCount(): Boolean {
        if (mDataList.isEmpty()) {
            return false
        }
        var fileCount = 0
        for (item in mDataList) {
            if (item.itemType != UploadItem.ADD_ITEM && item.uploadState == UploadItem.State.SUCCESS) {
                fileCount++
            }
        }
        return fileCount > 0
    }

    private fun checkButtonEnable() {
        mBtnConfirm.isEnabled = (mAddressTypeIndex != -1 && checkUploadFileCount())
    }

    override fun handleUploadPoa(responseResult: ResponseResult<Any?>) {
        if (responseResult.code == ResponseResult.SUCCESS_CODE) {
            GlobalInfoManager.getInstance().addListener(this)
            GlobalInfoManager.getInstance().update(GlobalInfoManager.UPDATE_USR_INFO)
        } else {
            responseResult.toast()
            LogUtils.d(TAG, "handleUploadPoa error: $responseResult")
        }
    }

    override fun onUpdate(obj: Any?) {
        if (obj is SystemUserInfo) {
            GlobalInfoManager.getInstance().remove(this)
            ResultOfKYCAuthActivity.startThis(mContext)
            finish()
        }
    }
}